home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1997 / MacHack 1997.toast / Hacks / Hacks ’94 / [√] Distribution Restricted! / Steve Sisak / TMFutures / FuturesDemo.c < prev    next >
C/C++ Source or Header  |  1994-06-26  |  6KB  |  222 lines

  1. #include "FuturesDemo.h"
  2. #include "Futures.h"
  3. #include "Threads.h"
  4. #include "AEThreads.h"
  5. #include <PPCToolBox.h>
  6. #include <EPPC.h>
  7. #include <AppleEvents.h>
  8. #include <string.h>
  9.  
  10. AEDesc                gNullDesc;            // A null descriptor record
  11. AEAddressDesc        gSelfAddress;        // A self-addressed address descriptor record
  12. ProcessSerialNumber    gSelfPSN;            // This application's psn
  13.  
  14. #pragma segment handlers
  15.  
  16. pascal OSErr HandlePing(AppleEvent question, AppleEvent answer, long /*handlerRefcon*/)
  17. {
  18.     char*            stringPtr;
  19.     char            stringBuffer[100];
  20.     long            actualSize;
  21.     DescType        actualType;
  22.     OSErr            theErr;
  23.     EventRecord        evt;
  24.  
  25. // Beep to indicate that the question was received
  26.  
  27.     while (EventAvail(everyEvent, &evt))
  28.     {
  29.         YieldToAnyThread();
  30.     }
  31.  
  32.     SysBeep(120);
  33.  
  34. // Extract a string from the question.
  35.  
  36.     theErr = AEGetParamPtr(&question, 'qstr', 'TEXT', &actualType, (Ptr) &stringBuffer, sizeof(stringBuffer)-1, &actualSize);
  37.  
  38. // Load a string into the answer.
  39.  
  40.     stringPtr = "I’m just fine.";
  41.     theErr = AEPutParamPtr(&answer, 'rstr', 'TEXT', stringPtr, strlen(stringPtr));
  42.  
  43.     return(noErr);
  44. }
  45.  
  46. pascal OSErr HandlePing1(AppleEvent /*event*/, AppleEvent /*reply*/, long /*handlerRefcon*/)
  47. {
  48.     OSErr            theErr;
  49.     TargetID        theTargetID;
  50.     PortInfoRec        thePortInfo;
  51.     AEAddressDesc    theAddressDesc;
  52.     AppleEvent        question;
  53.     AppleEvent        answer;
  54.     char*            stringPtr;
  55.     char            stringBuffer[100];
  56.     long            actualSize;
  57.     DescType        actualType;
  58.     long            i;
  59.  
  60. // Get the target address of the other process
  61.  
  62.     theErr = PPCBrowser("\p", "\p", false, &theTargetID.location, &thePortInfo, nil, "\p");
  63.     theTargetID.name = thePortInfo.name;
  64.     theErr = AECreateDesc(typeTargetID, (Ptr) &theTargetID, sizeof(TargetID), &theAddressDesc);
  65.  
  66. // Start the thread that pings
  67.  
  68.     for (i=0; i<30; i++)
  69.     {
  70.         YieldToAnyThread();
  71.  
  72. // Build an AppleEvent question that is addressed to the user selected target
  73.  
  74.         theErr = AECreateAppleEvent(kSillyEventClass, kPingEvent, &theAddressDesc, kAutoGenerateReturnID, kAnyTransactionID, &question);
  75.         
  76. // Load a string into the question.
  77.  
  78.         stringPtr = "Hello server, how are you doing?";
  79.         theErr = AEPutParamPtr(&question, 'qstr', 'TEXT', stringPtr, strlen(stringPtr));
  80.  
  81. // Ask the question
  82.  
  83.         theErr = Ask(&question, &answer);
  84.  
  85. // If the answer is not a future so soon after ask, something is probably wrong.
  86.  
  87.         // if (!IsFuture(&answer)) Debugger();
  88.  
  89. // Extract a string from the answer.  This will cause the thread to block until the answer is received.
  90.  
  91.         theErr = AEGetParamPtr(&answer, 'rstr', 'TEXT', &actualType, (Ptr) &stringBuffer, sizeof(stringBuffer)-1, &actualSize);
  92.  
  93. // If the answer is still a future after retrieving a string from the answer, something is definitely wrong.
  94.  
  95.         // if (IsFuture(&answer)) Debugger();
  96.  
  97. // Dispose of the answer and the question.
  98.         
  99.         theErr = AEDisposeDesc(&answer);
  100.         theErr = AEDisposeDesc(&question);
  101.     }
  102.  
  103. // Dispose of the address descriptor now that the thread no longer needs it.
  104.  
  105.     theErr = AEDisposeDesc(&theAddressDesc);
  106.     
  107.     return theErr;
  108. }
  109.  
  110. pascal OSErr HandlePing2(AppleEvent /*event*/, AppleEvent /*reply*/, long /*handlerRefcon*/)
  111. {
  112.  
  113.     OSErr            theErr;
  114.     TargetID        theTargetID;
  115.     PortInfoRec        thePortInfo;
  116.     AEAddressDesc    theAddressDesc;
  117.     AEAddressDesc    theAddressDesc2;
  118.     AppleEvent        question;
  119.     AppleEvent        question2;
  120.     AppleEvent        answer;
  121.     AppleEvent        answer2;
  122.     long i;
  123.  
  124. // Get the target addresses of the two processes
  125.  
  126.     theErr = PPCBrowser("\p", "\p", false, &theTargetID.location, &thePortInfo, nil, "\p");
  127.     theTargetID.name = thePortInfo.name;
  128.     theErr = AECreateDesc(typeTargetID, (Ptr) &theTargetID, sizeof(TargetID), &theAddressDesc);
  129.  
  130.     theErr = PPCBrowser("\p", "\p", false, &theTargetID.location, &thePortInfo, nil, "\p");
  131.     theTargetID.name = thePortInfo.name;
  132.     theErr = AECreateDesc(typeTargetID, (Ptr) &theTargetID, sizeof(TargetID), &theAddressDesc2);
  133.  
  134. // Start the thread that pings
  135.  
  136.     for (i=0; i<30; i++)
  137.     {
  138.         YieldToAnyThread();
  139.  
  140. // Build the questions.
  141.  
  142.         theErr = AECreateAppleEvent(kSillyEventClass, kPingEvent, &theAddressDesc, kAutoGenerateReturnID, kAnyTransactionID, &question);
  143.         theErr = AECreateAppleEvent(kSillyEventClass, kPingEvent, &theAddressDesc2, kAutoGenerateReturnID, kAnyTransactionID, &question2);
  144.         
  145. // Ask the questions.
  146.  
  147.         theErr = Ask(&question, &answer);
  148.         theErr = Ask(&question2, &answer2);
  149.  
  150. // Block until the answers become real.
  151.  
  152.         theErr = BlockUntilReal(&answer);
  153.         theErr = BlockUntilReal(&answer2);
  154.  
  155. // Dispose of the answers and the questions.
  156.  
  157.         theErr = AEDisposeDesc(&answer);
  158.         theErr = AEDisposeDesc(&answer2);
  159.         theErr = AEDisposeDesc(&question);
  160.         theErr = AEDisposeDesc(&question2);
  161.     }
  162.  
  163. // Dispose of the address descriptor now that the thread no longer needs it.
  164.  
  165.     theErr = AEDisposeDesc(&theAddressDesc);
  166.     theErr = AEDisposeDesc(&theAddressDesc2);
  167.     
  168.     return noErr;
  169. }
  170.  
  171. #pragma segment Main
  172.  
  173.  
  174. void SendSimpleAEvt(AEEventClass theAEEventClass, AEEventID theAEEventID)
  175. {
  176.     AppleEvent    myAppleEvent, reply;
  177.     
  178.         //    Create the Apple Event.
  179.     AECreateAppleEvent(theAEEventClass, theAEEventID, &gSelfAddress,
  180.                                     kAutoGenerateReturnID, kAnyTransactionID, &myAppleEvent);
  181.         //    Send the Apple Event.
  182.       AESend(&myAppleEvent, &reply, kAENoReply, kAENormalPriority,
  183.                                     kAEDefaultTimeout, nil, nil);
  184.                                 
  185.       AEDisposeDesc(&myAppleEvent);                // Dispose of the Apple Event.
  186. }
  187.  
  188.  
  189. pascal void InitFuturesDemo(void)
  190. {
  191.      gSelfPSN.highLongOfPSN = 0;
  192.      gSelfPSN.lowLongOfPSN = kCurrentProcess;        //* Use this instead of GetCurrentProcess *//
  193.      AECreateDesc(typeProcessSerialNumber,(Ptr)&gSelfPSN,sizeof(ProcessSerialNumber),&gSelfAddress);
  194.     gNullDesc.descriptorType = typeNull;        // Initialize the global null descriptor record.
  195.     gNullDesc.dataHandle = nil;
  196.  
  197. // Initialize the futures package
  198.  
  199.     InitFutures();
  200.  
  201. // Install a handler for the ping messages in AppleEvents, so that when we receive these events, this routine will be called
  202.  
  203. #if 0
  204.     AEInstallEventHandler(kSillyEventClass, kPingEvent, NewAEEventHandlerProc(HandlePing), 0, false);
  205. #else
  206.     AEInstallThreadedEventHandler(kSillyEventClass, kPingEvent, (AEEventHandlerProcPtr) &HandlePing, 0,
  207.                                   kCreateIfNeeded+kFPUNotNeeded, 0);
  208. #endif    
  209.     AEInstallThreadedEventHandler(kSillyEventClass, kPing1Event, (AEEventHandlerProcPtr) &HandlePing1, 0,
  210.                                   kCreateIfNeeded+kFPUNotNeeded, 0);
  211.     AEInstallThreadedEventHandler(kSillyEventClass, kPing2Event, (AEEventHandlerProcPtr) &HandlePing2, 0,
  212.                                   kCreateIfNeeded+kFPUNotNeeded, 0);
  213.  
  214. }
  215.  
  216.  
  217. pascal void CleanupFuturesDemo(void)
  218. {
  219.       AEDisposeDesc(&gSelfAddress);            // Dispose of my self-addressed descriptor.
  220. }
  221.  
  222.